#include "xstring.h"
#include "autodelete.hpp"
#include "common.h"

#include <cstring>
#include <cstdio>

astring &astring::fromUTF16(const wchar_t *p)
{
    clear();
    int size = wcslen(p) + 1;

    int new_size = ::WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL);
    if (!new_size)
    {
        E("WideCharToMultiByte");
        return *this;
    }
    AutoDeletes<char> q(new char[new_size]);
    new_size = ::WideCharToMultiByte(CP_ACP, 0, p, size, q, new_size, NULL, NULL);
    if (!new_size)
    {
        E("WideCharToMultiByte");
        return *this;
    }
    m_ptr = q.move();
    m_len = new_size;
    return *this;
}
astring &astring::FormatV(const char *fmt, va_list ap)
{
    clear();

    int len = _vscprintf(fmt, ap);
    if(len < 0)
        return *this;

    size_t size = (size_t)len + 1;
    AutoDeletes<char> p(new char[size]);
    if(!p)
        return *this;
    len = vsprintf_s(p, size, fmt, ap);
    if(len < 0)
        return *this;
    m_ptr = p.move();
    m_len = size;
    return *this;
}
astring &astring::Format(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);

    FormatV(fmt, ap);
    va_end(ap);
    return *this;
}
astring &astring::AppendFormatV(const char *fmt, va_list ap)
{
    astring s;
    *this += s.FormatV(fmt, ap);
    return *this;
}
astring &astring::AppendFormat(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    AppendFormatV(fmt, ap);
    va_end(ap);
    return *this;
}
astring::astring(const char *s)
{
    if(s && *s)
    {
        m_len = strlen(s) + 1;
        m_ptr = new char[m_len];
        memcpy(m_ptr, s, m_len * sizeof(char));
    }
    else
    {
        m_len = 0;
        m_ptr = nullptr;
    }
}
astring &astring::operator=(const char *s)
{
    clear();
    if(s && *s)
    {
        m_len = strlen(s) + 1;
        m_ptr = new char[m_len];
        memcpy(m_ptr, s, m_len * sizeof(char));
    }
    return *this;
}
